<script setup lang="ts">
import {
  computed,
  ref,
  onMounted,
  onBeforeUpdate,
  onUnmounted,
  useAttrs,
  watch
} from "vue";
import {
  fileDownload,
  fileToUrl,
  checkFileType,
  beforeAvatarUpload,
  // getImageDimension,
  getFileUrl
} from "./utils/file";
import { ElMessage } from "element-plus";
interface Props {
  modelValue?: any;
  loading?: boolean;
  limit?: number; //上传的最大数量 默认值1
  data?: any;
  name?: string;
  method?: string;
  action?: string;
  uploadSubmit?: any;
  accept?: string;
  fileName?: string;
  hideUploadComponent?: boolean; //是否显示上传的图标 默认显示
  autoUpload?: boolean;
  isImageSizeLimit?: boolean; //图片是否大小限制
  isImageCompress?: boolean; //图片是否压缩
  imageCompressQuality?: number; //图片压缩质量
  appointWidth?: number; //图片最大宽度
  appointHeight?: number; // 图片最大高度
}
const props = withDefaults(defineProps<Props>(), {
  modelValue: {}, //默认值
  loading: false,
  hideUploadComponent: false,
  limit: 1,
  data: {}, //附加参数
  name: "file", //上传的附加字段
  method: "post",
  action: "", //上传的路径
  accept: "image",
  fileName: "", //文件名称
  autoUpload: false,
  isImageSizeLimit: true,
  isImageCompress: true,
  imageCompressQuality: 0.8,
  appointWidth: undefined,
  appointHeight: undefined
});
const emit = defineEmits([
  "update:modelValue",
  "uploadCallback",
  "confirmCallback",
  "cancelCallback",
  "responseData"
]);
let value = computed(() => {
  return props.modelValue;
});
function closePopup() {
  emit("update:modelValue", false);
  emit("cancelCallback");
}
// 上传逻辑
// 上传图片
import { Download, ZoomIn } from "@element-plus/icons-vue";
import { genFileId } from "element-plus";
import type {
  UploadFile,
  UploadUserFile,
  UploadInstance,
  UploadProps,
  UploadRawFile
} from "element-plus";
const fileList = ref<any>([]);
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const disabled = ref(false);

const handleRemove = (file: UploadFile) => {
  console.log("fileList", fileList.value);
  upload.value!.handleRemove(file);
  setTimeout(() => {
    console.log(fileList.value);
    if (props.limit > 1) {
      emit("update:modelValue", fileList.value);
      emit("uploadCallback");
    } else {
      emit("update:modelValue", fileList.value[0]);
      emit("uploadCallback");
    }
  }, 100);
};

const handlePictureCardPreview = (file: UploadFile) => {
  dialogImageUrl.value = file.url!;
  dialogVisible.value = true;
};
const handleDownload = (file: UploadFile) => {
  if (file.raw) {
    fileDownload(file.raw, file.name);
  } else {
    const a = document.createElement("a"); // 创建a标签
    a.setAttribute("download", ""); // download属性
    a.setAttribute("href", file.url); // href链接
    a.click(); // 自执行点击事件
  }
};
// 覆盖前一个文件
const upload = ref<UploadInstance>();
const handleExceed: UploadProps["onExceed"] = files => {
  fileList.value = [];
  emit("update:modelValue", []);
  upload.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  upload.value!.handleStart(file);
};
// 文件改变时
const handleFileChange = async (file: UploadFile) => {
  try {
    if (props.accept === "svgaAndimage") {
      showSvgaView.value = false;
      if (checkFileType(file.raw) !== "image") {
        acceptType.value = "svga";
      } else {
        acceptType.value = "image";
      }
    }
    console.log(file, acceptType.value);
    // svga格式回调
    if (props.accept == "svga") {
      if (!file.name.includes("svga")) {
        ElMessage({
          message: "请上传svga格式的文件",
          type: "warning"
        });
        fileList.value = [];
        emit("update:modelValue", []);
        return;
      }
    }
    // image类型文件
    if (props.accept == "image") {
      if (checkFileType(file.raw) !== "image") {
        ElMessage({
          message: "请上传图片类型的文件",
          type: "warning"
        });
        fileList.value = [];

        emit("update:modelValue", []);
        return;
      }
    }
    // 音乐类型
    if (props.accept === "audio") {
      //  MP3、AAC M4A WAV
      let isReportMusic = false;
      if (file.name.includes(".")) {
        isReportMusic = ["MP3", "AAC", "M4A", "WAV"].includes(
          file.name.toLocaleUpperCase().split(".")[
            file.name.toLocaleUpperCase().split(".").length - 1
          ]
        );
      } else {
        isReportMusic = false;
      }
      console.log(file);
      if (checkFileType(file.raw) !== "audio") {
        ElMessage({
          message: "请上传音乐类型的文件",
          type: "warning"
        });
        fileList.value = [];
        emit("update:modelValue", []);
        return;
      } else if (!isReportMusic) {
        ElMessage({
          message: "仅支持MP3,AAC,M4A,WAV音乐类型的文件",
          type: "warning"
        });
        fileList.value = [];
        emit("update:modelValue", []);
        return;
      }
    }
    setTimeout(async () => {
      if (props.limit > 1) {
        if (props.accept === "audio") {
          fileList.value.forEach(async item => {
            let fileToUrlRes = await fileToUrl(item.raw);
            return {
              ...item,
              url: fileToUrlRes
            };
          });
        }
        emit(
          "update:modelValue",
          fileList.value.map(item => {
            return item.raw;
          })
        );
        emit(
          "uploadCallback",
          fileList.value.map(item => item.raw)
        );
      } else {
        console.log("file.raw", file);

        fileList.value[0] = file;
        fileList.value[0].url = await fileToUrl(file.raw);
        emit("update:modelValue", file.raw);
        emit("uploadCallback", file.raw);
        showSvgaView.value = true;
      }
    }, 100);
  } catch (error) {
    //code=10001 图片超过图片大小限制
    if (error.code === 10001) {
      ElMessage({
        message: error.msg,
        type: "warning"
      });
      fileList.value = [];
      emit("update:modelValue", []);
    }
  }
};
function submit() {
  console.log(upload.value, fileList.value);
  upload.value.submit();
}
function success(data: any) {
  emit("responseData", data.data);
}
defineExpose({
  upload,
  submit
});
const isEdit = ref(false);
/**显示组件 */
const showSvgaView = ref(false);
const acceptType = ref("image");
onMounted(() => {
  // console.log('props.modelValue', props.modelValue)
  if (props.modelValue) {
    // 图片
    if (props.accept === "image" || props.accept === "svga") {
      showSvgaView.value = true;
      setTimeout(() => {
        if (props.limit > 1) {
          fileList.value.push({
            url: props.modelValue[0].url
          });
          // fileList.value=props.modelValue
          dialogImageUrl.value = props.modelValue[0].url;
        } else {
          if (props.modelValue.url) {
            fileList.value.push({
              url: props.modelValue.url
            });
            dialogImageUrl.value = props.modelValue.url;
          }
          console.log(fileList.value);
        }
      }, 300);
    }
    //音频
    if (props.accept === "audio") {
      if (props.limit > 1) {
        fileList.value.push({
          url: props.modelValue[0].url
        });
        // fileList.value=props.modelValue
      } else {
        if (props.modelValue.url) {
          fileList.value.push({
            url: props.modelValue.url
          });
        }
      }
    }
    acceptType.value = props.accept;
    //svgaAndimage
    if (props.accept === "svgaAndimage") {
      acceptType.value = "image";
      showSvgaView.value = true;
      setTimeout(() => {
        if (props.limit > 1) {
          fileList.value.push({
            url: props.modelValue[0].url
          });
          // fileList.value=props.modelValue
          dialogImageUrl.value = props.modelValue[0].url;
        } else {
          if (props.modelValue.url) {
            fileList.value.push({
              url: props.modelValue.url
            });
            dialogImageUrl.value = props.modelValue.url;
          }
          console.log(fileList.value);
        }
      }, 300);
    }
  }
});
// 图片加载失败回调
function onErrorImage() {
  if (props.accept === "svgaAndimage") {
    acceptType.value = "svga";
  }
}
const attrs = useAttrs();
onUnmounted(() => {
  showSvgaView.value = false;
});
</script>

<template>
  <!-- 图片/头像 -->
  <div
    v-if="acceptType === 'image'"
    v-loading="loading"
    :class="
      hideUploadComponent && fileList?.length ? 'hide-upload-component' : ''
    "
  >
    <el-upload
      ref="upload"
      v-model:file-list="fileList"
      :accept="`${props.accept === 'svgaAndimage' ? '*' : 'image/*'}`"
      :method="method"
      :data="data"
      :name="name"
      :action="action"
      :limit="limit"
      :on-exceed="handleExceed"
      :on-change="handleFileChange"
      list-type="picture-card"
      :on-success="success"
      :multiple="limit > 1"
      :auto-upload="false"
    >
      <el-icon>
        <Plus />
      </el-icon>
      <template #file="{ file }">
        <div>
          <img
            class="el-upload-list__item-thumbnail"
            :src="file.url"
            alt=""
            @error="onErrorImage"
          />
          <span class="el-upload-list__item-actions">
            <span
              class="el-upload-list__item-preview"
              @click="handlePictureCardPreview(file)"
            >
              <el-icon><zoom-in /></el-icon>
            </span>
            <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleDownload(file)"
            >
              <el-icon>
                <Download />
              </el-icon>
            </span>
            <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleRemove(file)"
            >
              <el-icon>
                <Delete />
              </el-icon>
            </span>
          </span>
        </div>
      </template>
    </el-upload>
    <Teleport to="body">
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </Teleport>
  </div>
  <!-- 音乐类型 -->
  <div
    v-else-if="acceptType === 'audio'"
    v-loading="loading"
    class="w-100"
    :class="
      hideUploadComponent && fileList?.length ? 'hide-upload-component' : ''
    "
  >
    <el-upload
      ref="upload"
      v-model:file-list="fileList"
      class="w-100"
      :accept="accept"
      :method="method"
      :on-success="success"
      :on-change="handleFileChange"
      :data="data"
      :name="name"
      :action="action"
      :limit="limit"
      :on-exceed="handleExceed"
      :auto-upload="false"
      :multiple="limit > 1"
    >
      <template #trigger>
        <el-button type="primary">请选择文件</el-button>
      </template>
      <template #file="{ file }">
        <!-- {{ file }} -->
        <div
          class="h-box file-box"
          style="justify-content: space-between; align-items: center"
        >
          <audio controls :src="file.url">
            <a @click="handleDownload(file)"> Download audio </a>
          </audio>
          <el-icon
            style="opacity: 0; color: #818080"
            size="large"
            @click="handleRemove(file)"
          >
            <Close />
          </el-icon>
        </div>
        <!-- <div style="width: 100%;padding-top: 1px;background-color: #eee;">

                </div> -->
      </template>
    </el-upload>
  </div>
  <!-- 其他类型 -->
  <div
    v-else
    v-loading="loading"
    class="w-100"
    :class="
      hideUploadComponent && fileList?.length ? 'hide-upload-component' : ''
    "
  >
    <el-upload
      ref="upload"
      v-model:file-list="fileList"
      class="w-100"
      :accept="accept"
      :method="method"
      :on-success="success"
      :on-change="handleFileChange"
      :data="data"
      :name="name"
      :action="action"
      :limit="limit"
      :on-exceed="handleExceed"
      :auto-upload="autoUpload"
      :multiple="limit > 1"
    >
      <template #trigger>
        <el-button type="primary">请选择文件</el-button>
      </template>
    </el-upload>
    <!-- <el-button @click="submitTest">
    上传
</el-button> -->
  </div>
</template>

<style scoped lang="scss">
.file-box {
  padding: 5px 5px;
  border-bottom: 1px solid #eee;

  &:hover {
    > .el-icon {
      cursor: pointer;
      transition: opacity 2s ease;
      opacity: 1 !important;
    }
  }
}

.svga-bcg.el-dialog {
  background: transparent !important;
  background-color: transparent !important;
}

.hide-upload-component {
  :deep(.el-upload--picture-card) {
    display: none;
  }
}

:deep(.el-upload-list__item) {
  display: flex;
  justify-content: center;
}
</style>
